package app.component;

import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

import app.gif.ExportProperties;

/**
 * @author Evstigneev Kirill (kester)
 */
public class ProcessingPropertiesPanel extends JFrame {

	private static final String OUT_BASE = "res";
	private static final String MS = "ms.";
	private static final String PX = "px.";
	private final String DEFAULT_WIDTH = "250";
	private static final String DEFAULT_PERIOD = "1000";

	private final String projectName;
	private boolean okPressed;

	//export fields
	private JTextField widthField;
	private JTextField heightField;
	private JTextField periodField;
	private JTextField pathField;

	public ProcessingPropertiesPanel(final String projectName) {
		super("Out properties");
		this.projectName = projectName;
		this.okPressed = false;

		init();
		createForm();
	}

	private void init() {
		setSize(330, 220);
		setResizable(false);
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
	}

	private void createForm() {
		Box verticalBox = Box.createVerticalBox();
		getContentPane().add(verticalBox);

		widthField = new JTextField();
		final JPanel widthPanel = createLabelFieldLabelPanel("Width:", 26, widthField, DEFAULT_WIDTH, PX);
		verticalBox.add(widthPanel);

		heightField = new JTextField();
		final JPanel heightPanel = createLabelFieldLabelPanel("Height:", 23, heightField, null, PX);
		verticalBox.add(heightPanel);

		periodField = new JTextField();
		final JPanel periodPanel = createLabelFieldLabelPanel("Period:", 24, periodField, DEFAULT_PERIOD, MS);
		verticalBox.add(periodPanel);

		final JPanel outPanel = createOutPanel();
		verticalBox.add(outPanel);

		final JPanel acceptPanel = createAcceptPanel();
		verticalBox.add(acceptPanel);
	}

	private JPanel createLabelFieldLabelPanel( final String firstLabelText,
												   final int strutSize,
												   final JTextField field,
												   final String fieldValue,
												   final String secondLabelText ) {
		final JPanel periodPanel = new JPanel();
		final FlowLayout flowLayout = (FlowLayout) periodPanel.getLayout();
		flowLayout.setAlignment(FlowLayout.LEFT);

		final JLabel lblPeriod = new JLabel(firstLabelText);
		periodPanel.add(lblPeriod);

		final Component horizontalStrut = Box.createHorizontalStrut( strutSize );
		periodPanel.add(horizontalStrut);

		field.setText( fieldValue );
		field.setEditable(true);
		field.setColumns( 15 );
		periodPanel.add( field );

		final JLabel lblMs = new JLabel( secondLabelText );
		periodPanel.add(lblMs);

		return periodPanel;
	}

	private JPanel createOutPanel() {
		final JPanel outPanel = new JPanel();
		final FlowLayout flowLayout = (FlowLayout) outPanel.getLayout();
		flowLayout.setAlignment(FlowLayout.LEFT);

		final JLabel outFolder = new JLabel("Out folder:");
		outPanel.add(outFolder);

		final Component horizontalStrut = Box.createHorizontalStrut(5);
		outPanel.add(horizontalStrut);

		pathField = new JTextField();
		pathField.setColumns(15);
		pathField.setText(new File(OUT_BASE + File.separator + projectName + File.separator).getAbsolutePath());
		outPanel.add(pathField);

		final JButton btnSelect = new JButton("Select...");
		btnSelect.addActionListener( new ActionListener() {
			@Override
			public void actionPerformed(final ActionEvent e) {
				JFileChooser fc = new JFileChooser();
				fc.setDialogType( JFileChooser.OPEN_DIALOG );
				fc.setFileSelectionMode( JFileChooser.DIRECTORIES_ONLY );
				int result = fc.showOpenDialog( ProcessingPropertiesPanel.this );
				if ( result == JFileChooser.APPROVE_OPTION ) {
					final File f = fc.getSelectedFile();
					final String path = f.getAbsolutePath();
					pathField.setText(path);
				}
			}
		});
		outPanel.add(btnSelect);

		return outPanel;
	}

	private JPanel createAcceptPanel() {
		final JPanel acceptPanel = new JPanel();

		final JButton btnProcess = new JButton("Process");
		acceptPanel.add(btnProcess);
		btnProcess.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(final ActionEvent e) {
				okPressed = true;
				if ( !validateFields() ) {
					JOptionPane.showMessageDialog( ProcessingPropertiesPanel.this,
							"Check the correctness of parameters",
							"Validation",
							JOptionPane.ERROR_MESSAGE );
					return;
				}
				ProcessingPropertiesPanel.this.setVisible(false);
			}

		});

		final JButton btnCancel = new JButton("Cancel");
		btnCancel.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(final ActionEvent e) {
				okPressed = false;;
				ProcessingPropertiesPanel.this.setVisible(false);
			}
		});
		acceptPanel.add(btnCancel);

		return acceptPanel;
	}

	private boolean validateFields() {
		if( widthField.getText().isEmpty() && heightField.getText().isEmpty() ) {
			return false;
		}
		if( periodField.getText() == null ) {
			return false;
		}
		if ( !checkConvertable(widthField, heightField, periodField) ) {
			return false;
		}
		final String exportPath = pathField.getText();
		if ( !exportPath.isEmpty() ) {
			final File folder = new File( exportPath );
			folder.mkdirs();
			if( !folder.isDirectory() ) return false;
		}
		return true;
	}

	private boolean checkConvertable( final JTextField... fields ) {
		for (JTextField f : fields) {
			if (!f.getText().isEmpty()) {
				try {
					Integer.parseInt(f.getText());
				} catch (Exception e) {
					return false;
				}
			}
		}
		return true;
	}

	public boolean isOkPressed() {
		return okPressed;
	}

	public ExportProperties getExportProperties() {
		return new ExportProperties( !widthField.getText().isEmpty() ? Integer.valueOf(widthField.getText()) : null,
									 !heightField.getText().isEmpty() ? Integer.valueOf(heightField.getText()) : null,
									 Integer.valueOf( periodField.getText() ),
									 pathField.getText() );
	}

}
